package com.ve.usb;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.util.Log;
import android.widget.Toast;

import cn.wch.ch34xuartdriver.CH34xUARTDriver;

public class SerialService {
    private static final String TAG = SerialService.class.getSimpleName();
    public static final String ACTION_USB_PERMISSION = "com.ve.usb.permission";

    private static SerialService instance;
    private CH34xUARTDriver driver;

    private UsbDevice device;
    private UsbBroadcastReceiver usbReceiver;
    private Context context;
    private Runnable action;
    private byte parity = 0;
    private byte stopBit = 1;
    private byte dataBit = 8;
    private int baudRate = 9600;
    private byte flowControl = 0;

    public static SerialService getInstance() {
        return instance;
    }

    public static void init(Context context) {
        instance = new SerialService(context);
    }

    public static boolean isSerialDevice(UsbDevice device) {
//      return (device.getProductId() == 29987 && device.getVendorId() == 6790);
        return true;
    }

    public SerialService(Context con) {
        this.context=con.getApplicationContext();
        driver = new CH34xUARTDriver((UsbManager) context.getSystemService(Context.USB_SERVICE), context, ACTION_USB_PERMISSION);
        if (!driver.UsbFeatureSupported()) {
            Log.w(TAG, "SerialService: usb host is not supported");
        }
    }


    public boolean open(UsbDevice usbDevice) {
        if (!isSerialDevice(usbDevice)){
            return false;
        }
        close();
        device=usbDevice;
        Log.d(TAG, "open: "+device+ " :: "+driver.EnumerateDevice());
        driver.OpenDevice(usbDevice);
        if (!driver.UartInit()) {
            Log.w(TAG, "SerialService: UartInit fail");
            return false;
        }

        if (!setConfig(baudRate, dataBit, stopBit, parity, flowControl)) {
            Log.w(TAG, "SerialService: setConfig fail");
            return false;
        }

        return true;
    }
    public boolean setBaudRate(int baud){
       return setConfig(baud, dataBit, stopBit, parity, flowControl);
    }

    public int getBaudRate() {
        return baudRate;
    }

    public boolean setConfig(int baudRate, byte dataBit, byte stopBit, byte parity, byte flowControl) {
        if (driver.SetConfig(baudRate, dataBit, stopBit, parity, flowControl)) {
            this.baudRate=baudRate;
            this.dataBit=dataBit;
            this.stopBit=stopBit;
            this.parity=parity;
            this.flowControl=flowControl;
            return true;
        }
        return false;
    }

    public boolean isOpened(){
        return driver.isConnected();
    }

    public void close() {
        if (driver.isConnected()) {
            driver.CloseDevice();
        }
    }

    public boolean runWithPermission( UsbDevice device, Runnable runnable) {
        UsbManager manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
        action = runnable;
        if (!manager.hasPermission(device)) {
            usbReceiver = new UsbBroadcastReceiver();
            context.registerReceiver(usbReceiver, new IntentFilter(ACTION_USB_PERMISSION));
            PendingIntent mPendingIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
            manager.requestPermission(device, mPendingIntent);
            return false;
        } else {
            if (action != null) {
                action.run();
            }
            return true;
        }
    }

    public int read(byte[] data, int size) {
        return driver.ReadData(data,size);
    }

    public void write(byte[] bytes, int length) {
        driver.WriteData(bytes,length);
    }

    private class UsbBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(ACTION_USB_PERMISSION)) {
                boolean granted = intent.getExtras().getBoolean(UsbManager.EXTRA_PERMISSION_GRANTED);
                if (granted) {
                    if (action != null) {
                        action.run();
                    }
                } else {
                    Toast.makeText(context, "没有usb权限", Toast.LENGTH_SHORT).show();
                }
                context.unregisterReceiver(usbReceiver);
            }
        }
    }
}
